<template>
  <article class="page page-bacon-decrypt container">
    <h4 class="text-center">培根加密解密</h4>
    <form class="content">
      <div class="row">
        <div class="col-4">
          <fieldset>
            <legend>配置选项</legend>
            <div class="form-group">
              <div v-for="(btnGroup, gIndex) in btnGroupList" class="row btn-group-row" :key="gIndex">
                <div v-for="(btn, bIndex) in btnGroup" :class="[`col-${12 / btnGroup.length}`]" :key="bIndex">
					<button type="button" class="btn btn-secondary btn-block btn-sm"
						:class="{ active: btn.callback === btnActive }"
						@click="btnActive = btn.callback"
					>{{ btn.label }}</button>
                </div>
              </div>
            </div>
			<div class="form-group">
				<div class="alert alert-info">
					<div class="form-group-sm row">
						<div class="col-sm-1 col-form-label col-form-label-sm">
							<input class="form-check-input" type="checkbox" v-model="isSurrenal">
						</div>
						<div class="col-sm-10" style="line-height: 30px;">使用其它字符对代替AB</div>
					</div>
					<div class="form-group-sm row">
						<label class="col-sm-1 col-form-label col-form-label-sm">A</label>
						<div class="col-sm-10">
							<input type="text" class="form-control form-control-sm" v-model.trim="surrenalA" placeholder="示例:C"/>
						</div>
					</div>
					<div class="form-group-sm row">
						<label class="col-sm-1 col-form-label col-form-label-sm">B</label>
						<div class="col-sm-10">
							<input type="text" class="form-control form-control-sm" v-model.trim="surrenalB" placeholder="示例:D"/>
						</div>
					</div>
				</div>
			</div>
            <div class="form-group">
				<div class="form-group-sm">
					<x-button type="primary" block @click="result2content">将结果数据复制到原始数据</x-button>
				</div>
				<div class="form-group-sm">
					<x-button type="primary" block @click="clickHandler">处 理</x-button>
				</div>
            </div>
          </fieldset>
        </div>
        <div class="col-8">
          <fieldset>
            <legend>数据处理</legend>
			<textarea class="form-control" v-model.trim="content" rows="8" placeholder="原始数据"></textarea>
			<textarea class="form-control" v-model.trim="result" rows="8" placeholder="结果数据"></textarea>
          </fieldset>
        </div>
      </div>
      <div class="alert alert-secondary" role="alert">
        <div>1、本程序使用的是参考百度百科中提到的两种方式，方式一是每个字母对应不同的ab组合，方式二中i/j、u/v两组使用相同的值。</div>
        <div>2、暂不支持网上其它更加复杂的算法。</div>
      </div>
    </form>
  </article>
</template>

<script>
// 方式一
const charTable1 = {
  A: 'aaaaa', B: 'aaaab', C: 'aaaba', D: 'aaabb', E: 'aabaa', F: 'aabab', G: 'aabba',
  H: 'aabbb', I: 'abaaa', J: 'abaab', K: 'ababa', L: 'ababb', M: 'abbaa', N: 'abbab',
  O: 'abbba', P: 'abbbb', Q: 'baaaa', R: 'baaab', S: 'baaba', T: 'baabb', U: 'babaa',
  V: 'babab', W: 'babba', X: 'babbb', Y: 'bbaaa', Z: 'bbaab',
}
// 方式二
const charTable2 = {
  A: 'AAAAA', B: 'AAAAB', C: 'AAABA', D: 'AAABB', E: 'AABAA', F: 'AABAB', G: 'AABBA', 
  H: 'AABBB', I: 'ABAAA', J: 'ABAAA', K: 'ABAAB', L: 'ABABA', M: 'ABABB', N: 'ABBAA', 
  O: 'ABBAB', P: 'ABBBA', Q: 'ABBBB', R: 'BAAAA', S: 'BAAAB', T: 'BAABA', U: 'BAABB', 
  V: 'BAABB', W: 'BABAA', X: 'BABAB', Y: 'BABBA', Z: 'BABBB',
}

export default {
	name: 'bacon-decrypt',
	data () {
		return {
			content: '',
			result: '',
			btnActive: 'baconType1de',
			btnGroupList: [
				[ { label: '方式一加密', callback: 'baconType1en' }, { label: '方式一解密', callback: 'baconType1de' } ],
				[ { label: '方式二加密', callback: 'baconType2en' }, { label: '方式二解密', callback: 'baconType2de' } ],
				[ { label: '辅助：获取字符串各单词首字母', callback: 'getFirstLetter' } ],
				[ { label: '辅助：大小写字母转换为AB', callback: 'str2AB' } ],
				[ { label: '辅助：AB身份互换', callback: 'ABexchange' } ],
			],
			charTable1,
			charTable2,
			isSurrenal: false,
			surrenalA: '',
			surrenalB: '',
		}
	},
	computed: {
		charA () {
			return this.surrenalA || 'A'
		},
		charB () {
			return this.surrenalB || 'B'
		},
		charTable1Rev () {
			let result = {}
			for (let key in this.charTable1) {
				result[this.charTable1[key]] = key
			}
			return result
		},
		charTable2Rev () {
			let result = {}
			for (let key in this.charTable2) {
				let _key = this.charTable2[key]
				if (result[_key]) {
					result[_key] += `/${key}`
				} else {
					result[_key] = key
				}
			}
			return result
		},
	},
	methods: {
		clickHandler () {
			this.result = ''
			this[this.btnActive]()
		},
		result2content () {
			this.content = this.result
			this.result = ''
		},
		surrenalAB (str) {
			if (this.isSurrenal) {
				let reg_A = RegExp(this.charA, 'g')
				let reg_B = RegExp(this.charB, 'g')
				str = str.replace(reg_A, 'A').replace(reg_B, 'B')
			}
			return str
		},
		ABsurrenal (str) {
			if (this.isSurrenal) {
				str = str.replace(/A/g, this.charA).replace(/B/g, this.charB)
			}
			return str
		},
		baconType1en () {
			this.content = this.content.toUpperCase()
			for (let i = 0; i < this.content.length; i++) {
				if (this.content[i] in this.charTable1) {
					this.result += this.charTable1[this.content[i]]
				} else {
					this.result += this.content[i]
				}
			}
			this.result = this.ABsurrenal(this.result.toUpperCase())
		},
		baconType1de () {
			this.content = this.surrenalAB(this.content)
			this.content = this.content.toLowerCase().replace(/[^ab]/g, '')
			if (this.content.length % 5 != 0) {
				this.$toast('待处理字符串与当前算法不匹配！')
				return
			}
			while (this.content) {
				if (this.charTable1Rev[this.content.substring(0, 5)]) {
					this.result += this.charTable1Rev[this.content.substring(0, 5)]
				} else {
					this.$toast('待处理字符串与当前算法不匹配！')
					this.result = ''
					return
				}
				this.content = this.content.substring(5)
			}
		},
		baconType2en () {
			this.content = this.content.toUpperCase()
			for (let i = 0; i < this.content.length; i++) {
				if (this.content[i] in this.charTable2) {
					this.result += this.charTable2[this.content[i]]
				} else {
					this.result += this.content[i]
				}
			}
			this.result = this.ABsurrenal(this.result)
		},
		baconType2de () {
			this.content = this.surrenalAB(this.content)
			this.content = this.content.toUpperCase().replace(/[^AB]/g, '')
			if (this.content.length % 5 != 0) {
				this.$toast('待处理字符串与当前算法不匹配！')
				return;
			}
			while (this.content) {
				if (this.charTable2Rev[this.content.substring(0, 5)]) {
					this.result += this.charTable2Rev[this.content.substring(0, 5)]
				} else {
					this.$toast('待处理字符串与当前算法不匹配！')
					this.result = ''
					return
				}
				this.content = this.content.substring(5)
			}
		},
		getFirstLetter () {
			let contentArr = this.content.split(/[\W]/)
			contentArr.forEach(v => {
				if (v[0]) {
					this.result += v[0];
				}
			})
		},
		str2AB () {
			for (let i = 0; i < this.content.length; i++) {
				let c = this.content[i].charCodeAt()
				if (c >= 65 && c <= 90) {
					this.result += 'A'
				} else if (c >= 97 && c <= 122) {
					this.result += 'B'
				} else {
					this.result += this.content[i]
				}
			}
		},
		ABexchange () {
			this.result = this.content.toUpperCase().replace(/A/g, 'b').replace(/B/g, 'A').toUpperCase()
		},
	},
};
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.page-bacon-decrypt {
	display: flex;
	flex-direction: column;
	fieldset {
		height: 100%;
		textarea {
			height: calc(50% - 1.5em);
			& + textarea {
				margin-top: 1em;
			}
		}
	}
	.form-group-sm {
		& + .form-group-sm {
			margin-top: .5em;
		}
	}
	.content {
		height: 0;
		flex-grow: 1;
		overflow: hidden auto;
		.btn-group-row {
			margin-bottom: 2px;
			.col-6:first-child {
				padding-right: 1px;
			}
			.col-6:last-child {
				padding-left: 1px;
			}
		}
		.alert-secondary {
			margin-top: 1em;
			line-height: 2;
		}
	}
}
</style>
